package com.example.run_game;

import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.util.Log;
import android.widget.Toast;

//This class mirrors the DB entry
//Provides methods for getting and setting/calculating the player statistics
//also saves the player data to the db when told.
//Contains leveling up methods
public class Player
{
	private double totalAltGained;	
	private double totalDistance;
	private long totalTime;
	private int totalRuns; 
	private int totalCaloriesBurned;
	
	private String name;
	private int level;
	private int xp;
	private double weight;
	private double height;
	private Bitmap picture;
	
	private int nextLvlAt;
	
	private double avDistance;
	private long avTime;
	private double avSpeed;
	
	private double bestSpeed;
	private double furthestRun;
	private long longestRun;
	
	private Run rungui = null;
		
	DbManager db;
	AssetManager am;
	SoundManager sounds;
	private int totalScoreGained;
	
	Player(DbManager dbIn)
	{
		db = dbIn;
		totalAltGained = db.getTotalAlt();
		totalDistance = db.getTotalDistance();
		totalTime = db.getTotalTime();
		totalRuns = db.getTotalRuns();
		name = db.getPlayerName();
		level = db.getPlayerLevel(); 
		xp = db.getPlayerXP();
		avDistance = db.getAvDistance();
		avTime = db.getAvTime();
		avSpeed = db.getAvSpeed();
		totalCaloriesBurned = db.getTotalCaloriesBurned();
		weight = db.getWeight();
		height = db.getHeight();
		picture = db.getPicture();
		bestSpeed = db.getBestSpeed();
		furthestRun = db.getFurthestRun();
		longestRun = db.getLongestRun();
		if(avSpeed < 2)
			avSpeed = 2;
		totalScoreGained = 0;
		nextLvlAt = level*1000;
	}
	
	public void setRunGui(Run runIn)
	{
		rungui = runIn;
		Log.d("GAME: ", "XP: " + xp + "  Lvl: "+ level );
		double percentage = xp / nextLvlAt * 100;
		rungui.setProgressBarExp((int)percentage);	
		rungui.setLevelUp(level);	
	}
	
	public void printDetails()
	{
	  Log.d("totalAltGained", ""+totalAltGained);
	  Log.d("totalDistance", ""+totalDistance);
	  Log.d("totalTime", ""+totalTime);
	  Log.d("totalRuns", ""+totalRuns);
	  Log.d("name", ""+name);
	  Log.d("level", ""+level);
	  Log.d("xp", ""+xp);
	  Log.d("avDistance", ""+avDistance);
	  Log.d("avTime", ""+avTime);
	  Log.d("avSpeed", ""+avSpeed);
	  Log.d("Height", ""+height);
	  Log.d("Weight", ""+weight);
	  Log.d("Calories", ""+totalCaloriesBurned);
	  Log.d("Picture", ""+picture);
	  Log.d("bestSpeed", ""+bestSpeed);
	  Log.d("furthestRun", ""+furthestRun);
	  Log.d("longestRun", ""+longestRun);
	}
	
	public void save()
	{
		db.savePlayer(
				totalAltGained,
				totalDistance,
				totalTime, 
				totalRuns,
				name,
				level,
				xp,
				avDistance,
				avTime,
				avSpeed,
				weight,
				height,
				totalCaloriesBurned,
				picture,
				bestSpeed,
				furthestRun,
				longestRun
				);
	}
	
	public void	altGain(double altIn)
	{
		totalAltGained += altIn;
	}
	
	public void runCompleted(double distanceCovered, long timeTaken)
	{
		totalDistance += distanceCovered;
		totalTime += timeTaken;
		totalRuns++;
		
		avDistance = totalDistance / totalRuns;
		avTime = totalTime / totalRuns;
		if(totalTime == 0)
			avSpeed = 0;
		else
			avSpeed = totalDistance / totalTime;
		
		
	}
	
	public void setXPLevel(int xpIn, int lvlIn)
	{
		level = lvlIn;
		xp = xpIn;
	}
	
	public void changeName(String newName)
	{
		name = newName;
	}
	
	
	public double getTotalAltGained()
	{
		return totalAltGained;
	}
	public double getTotalDistance()
	{
		return totalDistance;
	}
	public long getTotalTime()
	{
		return totalTime;
	}
	public int getTotalRuns()
	{
		return totalRuns;
	}
	public String getName()
	{
		return name;
	}
	public int getLevel()
	{
		return level;
	}
	public int getXp()
	{
		return xp;
	}
	public double getAvDistance()
	{
		return avDistance;
	}
	public long getAvTime()
	{
		return avTime;
	}
	public double getAvSpeed()
	{
		return avSpeed;
	}
	public int getTotalCaloriesBurned()
	{
		return totalCaloriesBurned;
	}
	public double getWeight()
	{
		return weight;
	}
	public double getHeight()
	{
		return height;
	}	 
	public Bitmap getPicture()
	{
		return picture;
	}		
	public double getBestSpeed()
	{
		return bestSpeed;
	}
	public double getFurthestRun()
	{
		return furthestRun;
	}
	public long getLongestRun()
	{
		return longestRun;
	}

	/*
	 * Setters
	 */
	public void setName(String str)
	{
		this.name = str;
	}
	public void setTotalAltGained(double totalAltGained)
	{
		this.totalAltGained = totalAltGained;
	}
	public void setTotalDistance(double totalDistance)
	{
		this.totalDistance = totalDistance;
	}
	public void setTotalTime(long totalTime)
	{
		this.totalTime = totalTime;
	}
	public void setTotalRuns(int totalRuns)
	{
		this.totalRuns = totalRuns;
	}
	public void setTotalCaloriesBurned(int totalCaloriesBurned)
	{
		this.totalCaloriesBurned = totalCaloriesBurned;
	}
	public void setWeight(double weight)
	{
		this.weight = weight;
	}
	public void setHeight(double height)
	{
		this.height = height;
	}
	public void setPicture(Bitmap picture)
	{
		this.picture = picture;
	}
	public void setAvDistance(double avDistance)
	{
		this.avDistance = avDistance;
	}
	public void setAvTime(long avTime)
	{
		this.avTime = avTime;
	}
	public void setAvSpeed(double avSpeed)
	{
		this.avSpeed = avSpeed;
	}
	public void setBestSpeed(double bestSpeed)
	{
		this.bestSpeed = bestSpeed;
	}
	public void setFurthestRun(int furthestRun)
	{
		this.furthestRun = furthestRun;
	}
	public void setLongestRun(int longestRun)
	{
		this.longestRun = longestRun;
	}
	public void setWeight(Double kg)
	{
		this.weight = kg;
	}	
	public void setHeight(Double m)
	{
		this.height = m;
	}
		
	public void awardXP(int scoreUpdate)
	{
		Log.d("Score: ", "Xp awarded:" + scoreUpdate );
		int tempXp = xp;
		tempXp += scoreUpdate;
		totalScoreGained += scoreUpdate;
		while(tempXp >= nextLvlAt)
		{
			System.out.println("ding");
			levelUp(tempXp);
			tempXp -= nextLvlAt;
		}
		xp = tempXp;
		double percentage = xp * 100 / nextLvlAt;		
		if (rungui != null)
			rungui.setProgressBarExp((int)percentage);
	}

	public int getProgressBarPercentage()
	{
		
		double percentage = xp * 100 / nextLvlAt;		
		Log.d("Score: ", "Progress bar set to: " + (int)percentage);
		return (int)percentage;
	}
	
	private void levelUp(int tempXp)
	{
		level++;
		int remainder = tempXp - nextLvlAt;
		nextLvlAt = (level-1)*1000;
		xp = remainder;	
		String[] tracks = {""};
	
		if (rungui != null)
		{
			am = rungui.getApplicationContext().getAssets();
			sounds = new SoundManager(rungui.getApplicationContext(),am);
			Toast.makeText(rungui, "Level Increased" ,Toast.LENGTH_SHORT).show();
			tracks[0] = "ding.mp3";
			sounds.playSound(tracks);
		}
		
		Log.d("Score: ", "Level Up: from + " + (level -1) + " to " + level + "remainder" + remainder );
				
		double percentage = xp / nextLvlAt * 100;
		if (rungui != null)
		{
			rungui.setProgressBarExp((int)percentage);	
			rungui.setLevelUp(level);
		}
	}
	
	public int getTotalScore()
	{
		return totalScoreGained;
	}

	public void endGame(double distance, long timePassed, double altGain, int calories, double avRunSpeed, int exp)
	{
		//TODO maybe data mine this from the runhistory rather than accumlating
		if(distance > furthestRun)
			furthestRun = distance;
		if(timePassed > longestRun)
			longestRun = (int)timePassed;
		if(avRunSpeed > bestSpeed)
			bestSpeed = avRunSpeed;
		totalAltGained += altGain;
		totalDistance += distance;
		totalTime += timePassed;
		totalRuns++;
		totalCaloriesBurned += calories;	
		avDistance = totalDistance / totalRuns;
		avTime = totalTime / totalRuns;
		avSpeed = avDistance / avTime;	
		if (exp != -1)
			awardXP(exp);
		save();
	}

}
